//------------------------------------------------
//		I2C.c
//	I2C communication library
//	Arthur Benemann 07/10/2011
//------------------------------------------------
//
//	Description:
//	Initialize I2C peripheral for communication.
//  Contain some basic input/output rotines
//
//-----------------------------------------------
//
//	Requeriments:
//	I2C
//	I2C pins
//
//-----------------------------------------------

#include "picDev.h"
#include "I2C/I2C.h"


#define i2cWRITE 0
#define i2cREAD  1

#ifndef I2Cspeed
    #define I2Cspeed 37	// 400KHz
#endif

void i2cStart(void)
{
	// Enable a start condition
	I2C1CONbits.SEN = 1;
	while(I2C1CONbits.SEN);//wait
}

void i2cRestart(void)
{
	I2C1CONbits.RSEN = 1;
	while(I2C1CONbits.RSEN);//wait
}

void i2cStop(void)
{
	I2C1CONbits.PEN = 1;
	while(I2C1CONbits.PEN);		//wait
}


void i2cNack(void)
{
	I2C1CONbits.ACKDT=1;   		// Set for NotACk
	I2C1CONbits.ACKEN=1;		// Send Nack
	while(I2C1CONbits.ACKEN);   // wait for ACK to complete
	I2C1CONbits.ACKDT=0;
}

void i2cAck(void)
{
	I2C1CONbits.ACKDT=0;   		// Set for ACk
	I2C1CONbits.ACKEN=1;		// Send Ack
	while(I2C1CONbits.ACKEN);   // wait for ACK to complete
}

unsigned char i2cGetAck(void)
{
	return (!I2C1STATbits.ACKSTAT);//Return Ack Status
}

void i2cWrite(unsigned char byte)
{
	I2C1TRN=byte;
	while(I2C1STATbits.TBF);
}

unsigned char i2cWriteAck(unsigned char byte)
{
	I2C1TRN=byte;
	while(I2C1STATbits.TRSTAT==1);
	return (!I2C1STATbits.ACKSTAT);
}


unsigned char i2cRead(void)
{
	I2C1CONbits.RCEN=1;			//Enable Master receive
	while(!I2C1STATbits.RBF);	//Wait for receive bufer to be full
	return(I2C1RCV);			//Return data in buffer
}

void initI2C(void)
{
	// 7bit addressing
	I2C1CONbits.A10M=0;
	I2C1CONbits.SCLREL=0;

	// Clean slave addresses
	I2C1ADD=0;
	I2C1MSK=0;

	// Disable SMBus 
	I2C1CONbits.SMEN = 0; 

	// Baud rate setting
	I2C1BRG = I2Cspeed;
	
	// Enable I2C module
	I2C1CONbits.I2CEN = 1;	
}


unsigned char i2cWriteByte(unsigned char i2cADD,unsigned char ADD,unsigned char data)
{
	unsigned char error = 0;
	i2cStart();
   	error += !i2cWriteAck((i2cADD<<1)|i2cWRITE);
   	error += !i2cWriteAck(ADD);
	error += !i2cWriteAck(data);
	i2cStop();
	return error;
}

unsigned char i2cReadByte(unsigned char i2cADD,unsigned char ADD,unsigned char *data)
{
	unsigned char error = 0;
	i2cStart();
   	error += !i2cWriteAck((i2cADD<<1)|i2cWRITE);
	error += !i2cWriteAck(ADD);
	i2cStart();
   	error += !i2cWriteAck((i2cADD<<1)|i2cREAD);

	if(error) 
		{i2cStop(); return error;}

    *data = i2cRead();
	i2cNack();
	i2cStop();
	return error;
}

unsigned char i2cReadArray(unsigned char i2cADD,unsigned char ADD,unsigned char *data,unsigned char length)
{
	unsigned char error = 0;
	i2cStart();
   	error += !i2cWriteAck((i2cADD<<1)|i2cWRITE);
	error += !i2cWriteAck(ADD);
	i2cStart();
   	error += !i2cWriteAck((i2cADD<<1)|i2cREAD);

	if(error) 
		{i2cStop(); return error;}

	while(length-->1)
    {
		*data++ = i2cRead(); i2cAck();
	}
    *data = i2cRead(); i2cNack();
	i2cStop();

	return error;
}

void bufferSwap(int *p,int length){
    length=length/sizeof(int);
    while(length--){
        *p = (((unsigned int)*p)>>8)|((*p)<<8);
        p++;
    }
}
